home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / character.d < prev    next >
Encoding:
Text File  |  1994-05-07  |  13.6 KB  |  656 lines

  1. /*
  2.  Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
  3.  
  4. This file is part of GNU Common Lisp, herein referred to as GCL
  5.  
  6. GCL is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GCL is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
  14. License for more details.
  15.  
  16. You should have received a copy of the GNU Library General Public License 
  17. along with GCL; see the file COPYING.  If not, write to the Free Software
  18. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. /*
  22.     character.d
  23.  
  24.     character routines
  25. */
  26.  
  27. #include "include.h"
  28.  
  29. @(defun standard_char_p (c)
  30.     int i;
  31. @
  32.     check_type_character(&c);
  33.     if (char_font(c) != 0 || char_bits(c) != 0)
  34.         @(return Cnil)
  35.     i = char_code(c);
  36.     if (' ' <= i && i < '\177' || i == '\n')
  37.         @(return Ct)
  38.     @(return Cnil)
  39. @)
  40.  
  41. @(defun graphic_char_p (c)
  42.     int i;
  43. @
  44.     check_type_character(&c);
  45.     if (char_font(c) != 0 || char_bits(c) != 0)
  46.         @(return Cnil)
  47.     i = char_code(c);
  48.     if (' ' <= i && ' ' < '\177')
  49.         @(return Ct)
  50.     @(return Cnil)
  51. @)
  52.  
  53. @(defun string_char_p (c)
  54. @
  55.     check_type_character(&c);
  56.     if (char_font(c) != 0 || char_bits(c) != 0)
  57.         @(return Cnil)
  58.     @(return Ct)
  59. @)
  60.  
  61. @(defun alpha_char_p (c)
  62.     int i;
  63. @
  64.     check_type_character(&c);
  65.     if (char_font(c) != 0 || char_bits(c) != 0)
  66.         @(return Cnil)
  67.     i = char_code(c);
  68.     if (isalpha(i))
  69.         @(return Ct)
  70.     else
  71.         @(return Cnil)
  72. @)
  73.  
  74. @(defun upper_case_p (c)
  75. @
  76.     check_type_character(&c);
  77.     if (char_font(c) != 0 || char_bits(c) != 0)
  78.         @(return Cnil)
  79.     if (isUpper(char_code(c)))
  80.         @(return Ct)
  81.     @(return Cnil)
  82. @)
  83.  
  84. @(defun lower_case_p (c)
  85. @
  86.     check_type_character(&c);
  87.     if (char_font(c) != 0 || char_bits(c) != 0)
  88.         @(return Cnil)
  89.     if (isLower(char_code(c)))
  90.         @(return Ct)
  91.     @(return Cnil)
  92. @)
  93.  
  94. @(defun both_case_p (c)
  95. @
  96.     check_type_character(&c);
  97.     if (char_font(c) != 0 || char_bits(c) != 0)
  98.         @(return Cnil)
  99.     if (isUpper(char_code(c)) || isLower(char_code(c)))
  100.         @(return Ct)
  101.     else
  102.         @(return Cnil)
  103. @)
  104.  
  105. /*
  106.     Digitp(i, r) returns the weight of code i
  107.     as a digit of radix r.
  108.     If r > 36 or i is not a digit, -1 is returned.
  109. */
  110. digitp(i, r)
  111. int i, r;
  112. {
  113.     if ('0' <= i && i <= '9' && 1 < r && i < '0' + r)
  114.         return(i - '0');
  115.     if ('A' <= i && 10 < r && r <= 36 && i < 'A' + (r - 10))
  116.         return(i - 'A' + 10);
  117.     if ('a' <= i && 10 < r && r <= 36 && i < 'a' + (r - 10))
  118.         return(i - 'a' + 10);
  119.     return(-1);
  120. }
  121.  
  122. @(defun digit_char_p (c &optional (r `make_fixnum(10)`))
  123.     int d;
  124. @
  125.     check_type_character(&c);
  126.     check_type_non_negative_integer(&r);
  127.     if (type_of(r) == t_bignum)
  128.         @(return Cnil)
  129.     if (char_font(c) != 0 || char_bits(c) != 0)
  130.         @(return Cnil)
  131.     d = digitp(char_code(c), fix(r));
  132.     if (d < 0)
  133.         @(return Cnil)
  134.     @(return `make_fixnum(d)`)
  135. @)
  136.  
  137. @(defun alphanumericp (c)
  138.     int i;
  139. @
  140.     check_type_character(&c);
  141.     if (char_font(c) != 0 || char_bits(c) != 0)
  142.         @(return Cnil)
  143.     i = char_code(c);
  144.     if (isalphanum(i))
  145.         @(return Ct)
  146.     else
  147.         @(return Cnil)
  148. @)
  149.  
  150. bool
  151. char_eq(x, y)
  152. object x, y;
  153. {
  154.     return(char_code(x) == char_code(y)
  155.         && char_bits(x) == char_bits(y)
  156.         && char_font(x) == char_font(y));
  157. }
  158.  
  159. @(defun char_eq (c &rest)
  160.     int i;
  161. @
  162.     for (i = 0;  i < narg;  i++)
  163.         check_type_character(&vs_base[i]);
  164.     for (i = 1;  i < narg;  i++)
  165.         if (!char_eq(vs_base[i-1], vs_base[i]))
  166.             @(return Cnil)
  167.     @(return Ct)
  168. @)
  169.  
  170. @(defun char_neq (c &rest)
  171.     int i, j;
  172. @
  173.     for (i = 0;  i < narg;  i++)
  174.         check_type_character(&vs_base[i]);
  175.     if (narg == 0)
  176.         @(return Ct)
  177.     for (i = 1;  i < narg;  i++)
  178.         for (j = 0;  j < i;  j++)
  179.             if (char_eq(vs_base[j], vs_base[i]))
  180.                 @(return Cnil)
  181.     @(return Ct)
  182. @)
  183.  
  184.  
  185. int
  186. char_cmp(x, y)
  187. object x, y;
  188. {
  189.     if (char_font(x) < char_font(y))
  190.         return(-1);
  191.     if (char_font(x) > char_font(y))
  192.         return(1);
  193.     if (char_bits(x) < char_bits(y))
  194.         return(-1);
  195.     if (char_bits(x) > char_bits(y))
  196.         return(1);
  197.     if (char_code(x) < char_code(y))
  198.         return(-1);
  199.     if (char_code(x) > char_code(y))
  200.         return(1);
  201.     return(0);
  202. }
  203.  
  204. Lchar_cmp(s, t)
  205. int s, t;
  206. {
  207.     int narg, i;
  208.  
  209.     narg = vs_top - vs_base;
  210.     if (narg == 0)
  211.         too_few_arguments();
  212.     for (i = 0; i < narg; i++)
  213.         check_type_character(&vs_base[i]);
  214.     for (i = 1; i < narg; i++)
  215.         if (s*char_cmp(vs_base[i], vs_base[i-1]) < t) {
  216.             vs_top = vs_base+1;
  217.             vs_base[0] = Cnil;
  218.             return;
  219.         }
  220.     vs_top = vs_base+1;
  221.     vs_base[0] = Ct;
  222. }
  223.  
  224. Lchar_l()  { Lchar_cmp( 1, 1); }
  225. Lchar_g()  { Lchar_cmp(-1, 1); }
  226. Lchar_le() { Lchar_cmp( 1, 0); }
  227. Lchar_ge() { Lchar_cmp(-1, 0); }
  228.  
  229.  
  230. bool
  231. char_equal(x, y)
  232. object x, y;
  233. {
  234.     int i, j;
  235.  
  236.     i = char_code(x);
  237.     j = char_code(y);
  238.     if (isLower(i))
  239.         i -= 'a' - 'A';
  240.     if (isLower(j))
  241.         j -= 'a' - 'A';
  242.     return(i == j);
  243. }
  244.  
  245. @(defun char_equal (c &rest)
  246.     int i;
  247. @
  248.     for (i = 0;  i < narg;  i++)
  249.         check_type_character(&vs_base[i]);
  250.     for (i = 1;  i < narg;  i++)
  251.         if (!char_equal(vs_base[i-1], vs_base[i]))
  252.             @(return Cnil)
  253.     @(return Ct)
  254. @)
  255.  
  256. @(defun char_not_equal (c &rest)
  257.     int i, j;
  258. @
  259.     for (i = 0;  i < narg;  i++)
  260.         check_type_character(&vs_base[i]);
  261.     for (i = 1;  i < narg;  i++)
  262.         for (j = 0;  j < i;  j++)
  263.             if (char_equal(vs_base[j], vs_base[i]))
  264.                 @(return Cnil)
  265.     @(return Ct)
  266. @)
  267.  
  268.  
  269. int
  270. char_compare(x, y)
  271. object x, y;
  272. {
  273.     int i, j;
  274.  
  275.     i = char_code(x);
  276.     j = char_code(y);
  277.     if (isLower(i))
  278.         i -= 'a' - 'A';
  279.     if (isLower(j))
  280.         j -= 'a' - 'A';
  281.     if (i < j)
  282.         return(-1);
  283.     else if (i == j)
  284.         return(0);
  285.     else
  286.         return(1);
  287. }
  288.  
  289. Lchar_compare(s, t)
  290. int s, t;
  291. {
  292.     int narg, i;
  293.  
  294.     narg = vs_top - vs_base;
  295.     if (narg == 0)
  296.         too_few_arguments();
  297.     for (i = 0; i < narg; i++)
  298.         check_type_character(&vs_base[i]);
  299.     for (i = 1; i < narg; i++)
  300.         if (s*char_compare(vs_base[i], vs_base[i-1]) < t) {
  301.             vs_top = vs_base+1;
  302.             vs_base[0] = Cnil;
  303.             return;
  304.         }
  305.     vs_top = vs_base+1;
  306.     vs_base[0] = Ct;
  307. }
  308.  
  309. Lchar_lessp()        { Lchar_compare( 1, 1); }
  310. Lchar_greaterp()     { Lchar_compare(-1, 1); }
  311. Lchar_not_greaterp() { Lchar_compare( 1, 0); }
  312. Lchar_not_lessp()    { Lchar_compare(-1, 0); }
  313.  
  314.  
  315. object
  316. coerce_to_character(x)
  317. object x;
  318. {
  319. BEGIN:
  320.     switch (type_of(x)) {
  321.     case t_fixnum:
  322.         if (0 <= fix(x) && fix(x) < CHCODELIM)
  323.             return(code_char(fix(x)));
  324.         break;
  325.  
  326.     case t_character:
  327.         return(x);
  328.  
  329.     case t_symbol:
  330.     case t_string:
  331.         if (x->st.st_fillp == 1)
  332.             return(code_char(x->ust.ust_self[0]));
  333.         break;
  334.     }
  335.     vs_push(x);
  336.     x = wrong_type_argument(Scharacter, x);
  337.     vs_pop;
  338.     goto BEGIN;
  339. }
  340.  
  341. @(defun character (x)
  342. @
  343.     @(return `coerce_to_character(x)`)
  344. @)
  345.  
  346. @(defun char_code (c)
  347. @
  348.     check_type_character(&c);
  349.     @(return `make_fixnum(char_code(c))`)
  350. @)
  351.  
  352. @(defun char_bits (c)
  353. @
  354.     check_type_character(&c);
  355.     @(return `make_fixnum(char_bits(c))`)
  356. @)
  357.  
  358. @(defun char_font (c)
  359. @
  360.     check_type_character(&c);
  361.     @(return `make_fixnum(char_font(c))`)
  362. @)
  363.  
  364. @(defun code_char (c &o (b `make_fixnum(0)`) (f `make_fixnum(0)`))
  365.     object x;
  366. @
  367.     check_type_non_negative_integer(&c);
  368.     check_type_non_negative_integer(&b);
  369.     check_type_non_negative_integer(&f);
  370.     if (type_of(c) == t_bignum)
  371.         @(return Cnil)
  372.     if (type_of(b) == t_bignum)
  373.         @(return Cnil)
  374.     if (type_of(f) == t_bignum)
  375.         @(return Cnil)
  376.     if (fix(c)>=CHCODELIM || fix(b)>=CHBITSLIM || fix(f)>=CHFONTLIM)
  377.         @(return Cnil)
  378.     if (fix(b) == 0 && fix(f) == 0)
  379.         @(return `code_char(fix(c))`)
  380.     x = alloc_object(t_character);
  381.     char_code(x) = fix(c);
  382.     char_bits(x) = fix(b);
  383.     char_font(x) = fix(f);
  384.     @(return x)
  385. @)
  386.  
  387. @(defun make_char (c &o (b `make_fixnum(0)`) (f `make_fixnum(0)`))
  388.     object x;
  389.     int code;
  390. @
  391.     check_type_character(&c);
  392.     code = char_code(c);
  393.     check_type_non_negative_integer(&b);
  394.     check_type_non_negative_integer(&f);
  395.     if (type_of(b) == t_bignum)
  396.         @(return Cnil)
  397.     if (type_of(f) == t_bignum)
  398.         @(return Cnil)
  399.     if (fix(b)>=CHBITSLIM || fix(f)>=CHFONTLIM)
  400.         @(return Cnil)
  401.     if (fix(b) == 0 && fix(f) == 0)
  402.         @(return `code_char(code)`)
  403.     x = alloc_object(t_character);
  404.     char_code(x) = code;
  405.     char_bits(x) = fix(b);
  406.     char_font(x) = fix(f);
  407.     @(return x)
  408. @)
  409.  
  410. @(defun char_upcase (c)
  411. @
  412.     check_type_character(&c);
  413.     if (char_font(c) != 0 || char_bits(c) != 0)
  414.         @(return c)
  415.     if (isLower(char_code(c)))
  416.         @(return `code_char(char_code(c) - ('a' - 'A'))`)
  417.     else
  418.         @(return c)
  419. @)
  420.  
  421. @(defun char_downcase (c)
  422. @
  423.     check_type_character(&c);
  424.     if (char_font(c) != 0 || char_bits(c) != 0)
  425.         @(return Cnil)
  426.     if (isUpper(char_code(c)))
  427.         @(return `code_char(char_code(c) + ('a' - 'A'))`)
  428.     else
  429.         @(return c)
  430. @)
  431.  
  432. int
  433. digit_weight(w, r)
  434. int w, r;
  435. {
  436.     if (r < 2 || r > 36 || w < 0 || w >= r)
  437.         return(-1);
  438.     if (w < 10)
  439.         return(w + '0');
  440.     else
  441.         return(w - 10 + 'A');
  442. }
  443.  
  444. @(defun digit_char (w
  445.             &optional
  446.             (r `make_fixnum(10)`)
  447.             (f `make_fixnum(0)`))
  448.     object x;
  449.     int dw;
  450. @
  451.     check_type_non_negative_integer(&w);
  452.     check_type_non_negative_integer(&r);
  453.     check_type_non_negative_integer(&f);
  454.     if (type_of(w) == t_bignum)
  455.         @(return Cnil)
  456.     if (type_of(r) == t_bignum)
  457.         @(return Cnil)
  458.     if (type_of(f) == t_bignum)
  459.         @(return Cnil)
  460.     dw = digit_weight(fix(w), fix(r));
  461.     if (dw < 0)
  462.         @(return Cnil)
  463.     if (fix(f) >= CHFONTLIM)
  464.         @(return Cnil)
  465.     if (fix(f) == 0)
  466.         @(return `code_char(dw)`)
  467.     x = alloc_object(t_character);
  468.     char_code(x) = dw;
  469.     char_bits(x) = 0;
  470.     char_font(x) = fix(f);
  471.     @(return x)
  472. @)
  473.  
  474. @(defun char_int (c)
  475.     int i;
  476. @
  477.     check_type_character(&c);
  478.     i = (char_font(c)*CHBITSLIM + char_bits(c))*CHCODELIM
  479.       + char_code(c);
  480.     @(return `make_fixnum(i)`)
  481. @)
  482.  
  483. @(defun int_char (x)
  484.     int i, c, b, f;
  485. @
  486.     check_type_non_negative_integer(&x);
  487.     if (type_of(x) == t_bignum)
  488.         @(return Cnil)
  489.     i = fix(x);
  490.     c = i % CHCODELIM;
  491.     i /= CHCODELIM;
  492.     b = i % CHBITSLIM;
  493.     i /= CHBITSLIM;
  494.     f = i % CHFONTLIM;
  495.     i /= CHFONTLIM;
  496.     if (i > 0)
  497.         @(return Cnil)
  498.     if (b == 0 && f == 0)
  499.         @(return `code_char(c)`)
  500.     x = alloc_object(t_character);
  501.     char_code(x) = c;
  502.     char_bits(x) = b;
  503.     char_font(x) = f;
  504.     @(return x)
  505. @)
  506.  
  507. @(defun char_name (c)
  508. @
  509.     check_type_character(&c);
  510.     if (char_bits(c) != 0 || char_font(c) != 0)
  511.         @(return Cnil)
  512.     switch (char_code(c)) {
  513.     case '\r':
  514.         @(return STreturn)
  515.  
  516.     case ' ':
  517.         @(return STspace)
  518.  
  519.     case '\177':
  520.         @(return STrubout)
  521.     
  522.     case '\f':
  523.         @(return STpage)
  524.  
  525.     case '\t':
  526.         @(return STtab)
  527.  
  528.     case '\b':
  529.         @(return STbackspace)
  530.  
  531.     case '\n':
  532.         @(return STnewline)
  533.     }
  534.     @(return Cnil)
  535. @)
  536.  
  537. @(defun name_char (s)
  538. @
  539.     s = coerce_to_string(s);
  540.     if (string_equal(s, STreturn))
  541.         @(return `code_char('\r')`)
  542.     if (string_equal(s, STspace))
  543.         @(return `code_char(' ')`)
  544.     if (string_equal(s, STrubout))
  545.         @(return `code_char('\177')`)
  546.     if (string_equal(s, STpage))
  547.         @(return `code_char('\f')`)
  548.     if (string_equal(s, STtab))
  549.         @(return `code_char('\t')`)
  550.     if (string_equal(s, STbackspace))
  551.         @(return `code_char('\b')`)
  552.     if (string_equal(s, STlinefeed) || string_equal(s, STnewline))
  553.         @(return `code_char('\n')`)
  554.     @(return Cnil)
  555. @)
  556.  
  557. @(defun char_bit (c n)
  558. @
  559.     check_type_character(&c);
  560.     FEerror("Cannot get char-bit of ~S.", 1, c);
  561. @)
  562.  
  563. @(defun set_char_bit (c n v)
  564. @
  565.     check_type_character(&c);
  566.     FEerror("Cannot set char-bit of ~S.", 1, c);
  567. @)
  568.  
  569. init_character()
  570. {
  571.     object ch;
  572.     int i;
  573.  
  574.     for (i = 0;  i < CHCODELIM;  i++) {
  575.         character_table[i].t = (short)t_character;
  576.         character_table[i].ch_code = i;
  577.         character_table[i].ch_font = 0;
  578.         character_table[i].ch_bits = 0;
  579.     }
  580. #ifdef AV
  581.     for (i = -128;  i < 0;  i++) {
  582.         character_table[i].t = (short)t_character;
  583.         character_table[i].ch_code = i+CHCODELIM;
  584.         character_table[i].ch_font = 0;
  585.         character_table[i].ch_bits = 0;
  586.     }
  587. #endif
  588.  
  589.      make_constant("CHAR-CODE-LIMIT", make_fixnum(CHCODELIM));
  590.      make_constant("CHAR-FONT-LIMIT", make_fixnum(CHFONTLIM));
  591.      make_constant("CHAR-BITS-LIMIT", make_fixnum(CHBITSLIM));
  592.  
  593.     STreturn = make_simple_string("RETURN");
  594.     enter_mark_origin(&STreturn);
  595.     STspace = make_simple_string("SPACE");
  596.     enter_mark_origin(&STspace);
  597.     STrubout = make_simple_string("RUBOUT");
  598.     enter_mark_origin(&STrubout);
  599.     STpage = make_simple_string("PAGE");
  600.     enter_mark_origin(&STpage);
  601.     STtab = make_simple_string("TAB");
  602.     enter_mark_origin(&STtab);
  603.     STbackspace = make_simple_string("BACKSPACE");
  604.     enter_mark_origin(&STbackspace);
  605.     STlinefeed = make_simple_string("LINEFEED");
  606.     enter_mark_origin(&STlinefeed);
  607.  
  608.     STnewline = make_simple_string("NEWLINE");
  609.     enter_mark_origin(&STnewline);
  610.  
  611.     make_constant("CHAR-CONTROL-BIT", make_fixnum(0));
  612.     make_constant("CHAR-META-BIT", make_fixnum(0));
  613.     make_constant("CHAR-SUPER-BIT", make_fixnum(0));
  614.     make_constant("CHAR-HYPER-BIT", make_fixnum(0));
  615. }
  616.  
  617. init_character_function()
  618. {
  619.     make_function("STANDARD-CHAR-P", Lstandard_char_p);
  620.     make_function("GRAPHIC-CHAR-P", Lgraphic_char_p);
  621.     make_function("STRING-CHAR-P", Lstring_char_p);
  622.     make_function("ALPHA-CHAR-P", Lalpha_char_p);
  623.     make_function("UPPER-CASE-P", Lupper_case_p);
  624.     make_function("LOWER-CASE-P", Llower_case_p);
  625.     make_function("BOTH-CASE-P", Lboth_case_p);
  626.     make_function("DIGIT-CHAR-P", Ldigit_char_p);
  627.     make_function("ALPHANUMERICP", Lalphanumericp);
  628.     make_function("CHAR=", Lchar_eq);
  629.     make_function("CHAR/=", Lchar_neq);
  630.     make_function("CHAR<", Lchar_l);
  631.     make_function("CHAR>", Lchar_g);
  632.     make_function("CHAR<=", Lchar_le);
  633.     make_function("CHAR>=", Lchar_ge);
  634.     make_function("CHAR-EQUAL", Lchar_equal);
  635.     make_function("CHAR-NOT-EQUAL", Lchar_not_equal);
  636.     make_function("CHAR-LESSP", Lchar_lessp);
  637.     make_function("CHAR-GREATERP", Lchar_greaterp);
  638.     make_function("CHAR-NOT-GREATERP", Lchar_not_greaterp);
  639.     make_function("CHAR-NOT-LESSP", Lchar_not_lessp);
  640.     make_function("CHARACTER", Lcharacter);
  641.     make_function("CHAR-CODE", Lchar_code);
  642.     make_function("CHAR-BITS", Lchar_bits);
  643.     make_function("CHAR-FONT", Lchar_font);
  644.     make_function("CODE-CHAR", Lcode_char);
  645.     make_function("MAKE-CHAR", Lmake_char);
  646.     make_function("CHAR-UPCASE", Lchar_upcase);
  647.     make_function("CHAR-DOWNCASE", Lchar_downcase);
  648.     make_function("DIGIT-CHAR", Ldigit_char);
  649.     make_function("CHAR-INT", Lchar_int);
  650.     make_function("INT-CHAR", Lint_char);
  651.     make_function("CHAR-NAME", Lchar_name);
  652.     make_function("NAME-CHAR", Lname_char);
  653.     make_function("CHAR-BIT", Lchar_bit);
  654.     make_function("SET-CHAR-BIT", Lset_char_bit);
  655. }
  656.